package cn.signalpha.modules.queue.handle;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.hutool.core.date.DateUtil;
import cn.signalpha.common.enums.StatusEnum;
import cn.signalpha.core.sms.model.SmsData;
import cn.signalpha.core.sms.model.SmsResponse;
import cn.signalpha.core.tool.jackson.JsonUtil;
import cn.signalpha.core.tool.utils.Func;
import cn.signalpha.core.tool.utils.ObjectUtil;
import cn.signalpha.core.tool.utils.StringUtil;
import cn.signalpha.modules.base.dto.NoticeDTO;
import cn.signalpha.modules.base.entity.NoticeTemplate;
import cn.signalpha.modules.base.entity.enums.NoticeTypeEnum;
import cn.signalpha.modules.base.service.NoticeTemplateService;
import cn.signalpha.modules.com.entity.User;
import cn.signalpha.modules.com.entity.UserOauth;
import cn.signalpha.modules.com.entity.enums.UserSourceEnum;
import cn.signalpha.modules.com.service.UserOauthService;
import cn.signalpha.modules.com.service.UserService;
import cn.signalpha.modules.queue.enums.RedisDelayQueueEnum;
import cn.signalpha.modules.resource.builder.sms.SmsBuilder;
import cn.signalpha.modules.shop.entity.*;
import cn.signalpha.modules.shop.service.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 支付订单通知
 *
 * @author signalpha
 */
@Slf4j
@AllArgsConstructor
@Component("notice")
public class Notice implements RedisDelayQueueHandle<NoticeDTO> {

	private final SmsBuilder smsBuilder;
	private final UserService userService;
	private final WxMpService wxMpService;
	private final WxMaService wxMaService;
	private final OrderService orderService;
	private final LogisticsService logisticsService;
	private final UserOauthService userOauthService;
	private final PlaceApplyService placeApplyService;
	private final OrderRefundService orderRefundService;
	private final SellerApplyService sellerApplyService;
	private final NoticeTemplateService noticeTemplateService;
	private final OrderLogisticsService orderLogisticsService;
	private final OrderSettlePlaceService orderSettlePlaceService;
	private final OrderLogisticsDetailService orderLogisticsDetailService;

	@Override
	public void execute(NoticeDTO noticeDTO) {
		String queueCode = RedisDelayQueueEnum.NOTICE.getCode();
		log.info("(延时队列开始消费) 队列键：{}，队列值：{}，消费时间：{}", queueCode, JsonUtil.toJson(noticeDTO), DateUtil.now());

		NoticeTemplate noticeTemplate = noticeTemplateService.getByType(noticeDTO.getType());
		if(noticeTemplate.getStatus().equals(StatusEnum.OFF.getType())){
			return;
		}

		//订单发货通知
		if(NoticeTypeEnum.ORDER_SEND_OUT.getType().equals(noticeDTO.getType())){
			OrderLogistics orderLogistics = orderLogisticsService.getById(noticeDTO.getTargetId());
			Order order = ObjectUtil.isNotEmpty(orderLogistics) ? orderService.getByOrderNo(orderLogistics.getOrderNo()) : orderService.getById(noticeDTO.getTargetId());
			if(noticeTemplate.getIsMp() == 1){
				UserOauth userOauth = userOauthService.getByUserIdAndSource(order.getUserId(), UserSourceEnum.WECHAT_PUBLIC.getValue());
				if(ObjectUtil.isNotEmpty(userOauth) && userOauth.getStatus() == 1){
					WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
						.toUser(userOauth.getOpenId())
						.templateId(noticeTemplate.getMpId())
						.url(StringUtil.isBlank(noticeTemplate.getMpUrl()) ?  "" : noticeTemplate.getMpUrl() + order.getId())
						.build();
					templateMessage.addData(new WxMpTemplateData("character_string2", order.getOrderNo()));
					templateMessage.addData(new WxMpTemplateData("character_string4", Func.toStrWithEmpty(orderLogistics.getLogisticsNo(), "0")));
					templateMessage.addData(new WxMpTemplateData("thing5", Func.toStrWithEmpty(logisticsService.getById(orderLogistics.getLogisticsId()).getName(), "无")));
					templateMessage.addData(new WxMpTemplateData("time3", DateUtil.formatDateTime(orderLogistics.getCreateTime())));
					try {
						wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
					} catch (WxErrorException e) {
						log.error("【微信公众号模板阅消】发送失败, {}", e.getMessage());
					}
				}
			}
			if(noticeTemplate.getIsMa() == 1){
				UserOauth userOauth = userOauthService.getByUserIdAndSource(order.getUserId(), UserSourceEnum.WECHAT_MINI_APP.getValue());
				if(ObjectUtil.isNotEmpty(userOauth)){
					List<WxMaSubscribeMessage.MsgData> data  = Arrays.asList(
						new WxMaSubscribeMessage.MsgData("character_string2", order.getOrderNo()),
						new WxMaSubscribeMessage.MsgData("character_string4", Func.toStrWithEmpty(orderLogistics.getLogisticsNo(), "0")),
						new WxMaSubscribeMessage.MsgData("thing5", Func.toStrWithEmpty(logisticsService.getById(orderLogistics.getLogisticsId()).getName(), "无")),
						new WxMaSubscribeMessage.MsgData("time3", DateUtil.formatDateTime(orderLogistics.getCreateTime()))
					);
					WxMaSubscribeMessage subscribeMessage = WxMaSubscribeMessage.builder()
						.toUser(userOauth.getOpenId())
						.templateId(noticeTemplate.getMaId())
						.page(StringUtil.isBlank(noticeTemplate.getMaUrl()) ?  "" : noticeTemplate.getMaUrl() + order.getId())
						.data(data)
						.build();
					try {
						wxMaService.getMsgService().sendSubscribeMsg(subscribeMessage);
					} catch (WxErrorException e) {
						log.error("【微信订阅消息】发送失败, {}", e.getMessage());
					}
				}
			}
		}

		//订单售后通知
		if(NoticeTypeEnum.ORDER_REFUND.getType().equals(noticeDTO.getType())){
			OrderRefund orderRefund = orderRefundService.getById(noticeDTO.getTargetId());
			String result, hint;
			if(orderRefund.getRefundStatus() == 1){
				result = "商家同意";
				hint = "请尽快将商品寄回并填写物流单号";
			}else if(orderRefund.getRefundStatus() == 3){
				result = "商家同意";
				hint = "货款已退回,可到售后订单查看详情";
			}else{
				result = "商家拒绝";
				hint = "在售后订单查看详情";
			}

			if(noticeTemplate.getIsMp() == 1){
				UserOauth userOauth = userOauthService.getByUserIdAndSource(orderRefund.getUserId(), UserSourceEnum.WECHAT_PUBLIC.getValue());
				if(ObjectUtil.isNotEmpty(userOauth) && userOauth.getStatus() == 1){
					WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
						.toUser(userOauth.getOpenId())
						.templateId(noticeTemplate.getMpId())
						.url(StringUtil.isBlank(noticeTemplate.getMpUrl()) ?  "" : noticeTemplate.getMpUrl() + orderRefund.getId())
						.build();
					templateMessage.addData(new WxMpTemplateData("character_string1", orderRefund.getOrderNo()));
					templateMessage.addData(new WxMpTemplateData("const5", orderRefund.getRefundType() == 1 ? "仅退款" : "退货退款"));
					templateMessage.addData(new WxMpTemplateData("const7", result));
					templateMessage.addData(new WxMpTemplateData("amount6", String.valueOf(orderRefund.getRefundMoney())));
					try {
						wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
					} catch (WxErrorException e) {
						log.error("【微信公众号模板阅消】发送失败, {}", e.getMessage());
					}
				}
			}
			if(noticeTemplate.getIsMa() == 1){
				UserOauth userOauth = userOauthService.getByUserIdAndSource(orderRefund.getUserId(), UserSourceEnum.WECHAT_MINI_APP.getValue());
				if(ObjectUtil.isNotEmpty(userOauth)){
					List<WxMaSubscribeMessage.MsgData> data  = Arrays.asList(
						new WxMaSubscribeMessage.MsgData("character_string2", orderRefund.getOrderNo()),
						new WxMaSubscribeMessage.MsgData("phrase1", orderRefund.getRefundType() == 1 ? "退款" : "退货退款"),
						new WxMaSubscribeMessage.MsgData("phrase11", result),
						new WxMaSubscribeMessage.MsgData("amount12", String.valueOf(orderRefund.getRefundMoney())),
						new WxMaSubscribeMessage.MsgData("thing5", hint)
					);
					WxMaSubscribeMessage subscribeMessage = WxMaSubscribeMessage.builder()
						.toUser(userOauth.getOpenId())
						.templateId(noticeTemplate.getMaId())
						.page(StringUtil.isBlank(noticeTemplate.getMaUrl()) ?  "" : noticeTemplate.getMaUrl() + orderRefund.getId())
						.data(data)
						.build();
					try {
						wxMaService.getMsgService().sendSubscribeMsg(subscribeMessage);
					} catch (WxErrorException e) {
						log.error("【微信订阅消息】发送失败, {}", e.getMessage());
					}
				}
			}
		}

		//新客绑定通知
		if(NoticeTypeEnum.USER_BINDING.getType().equals(noticeDTO.getType())){
			User user = userService.getById(noticeDTO.getTargetId());
			if(noticeTemplate.getIsMa() == 1){
				UserOauth userOauth = userOauthService.getByUserIdAndSource(user.getParentId(), UserSourceEnum.WECHAT_MINI_APP.getValue());
				if(ObjectUtil.isNotEmpty(userOauth)){
					List<WxMaSubscribeMessage.MsgData> data  = Arrays.asList(
						new WxMaSubscribeMessage.MsgData("thing1", Func.toStrWithEmpty(user.getNickName(), "微信用户")),
						new WxMaSubscribeMessage.MsgData("date2", DateUtil.formatDateTime(user.getBindingTime())),
						new WxMaSubscribeMessage.MsgData("thing5", "提示")
					);
					WxMaSubscribeMessage subscribeMessage = WxMaSubscribeMessage.builder()
						.toUser(userOauth.getOpenId())
						.templateId(noticeTemplate.getMaId())
						.page(StringUtil.isBlank(noticeTemplate.getMaUrl()) ?  "" : noticeTemplate.getMaUrl())
						.data(data)
						.build();
					try {
						wxMaService.getMsgService().sendSubscribeMsg(subscribeMessage);
					} catch (WxErrorException e) {
						log.error("【微信订阅消息】发送失败, {}", e.getMessage());
					}
				}
			}
		}

		//佣金待入账通知
		if(NoticeTypeEnum.BROKERAGE.getType().equals(noticeDTO.getType())){
			OrderSettlePlace orderSettlePlace = orderSettlePlaceService.getById(noticeDTO.getTargetId());
			if(noticeTemplate.getIsMa() == 1){
				UserOauth userOauth = userOauthService.getByUserIdAndSource(orderSettlePlace.getUserId(), UserSourceEnum.WECHAT_MINI_APP.getValue());
				if(ObjectUtil.isNotEmpty(userOauth)){
					List<WxMaSubscribeMessage.MsgData> data  = Arrays.asList(
						new WxMaSubscribeMessage.MsgData("character_string1", orderSettlePlace.getOrderNo()),
						new WxMaSubscribeMessage.MsgData("amount2", String.valueOf(orderSettlePlace.getPayAmount())),
						new WxMaSubscribeMessage.MsgData("amount5", String.valueOf(orderSettlePlace.getSettleAmount()))
					);
					WxMaSubscribeMessage subscribeMessage = WxMaSubscribeMessage.builder()
						.toUser(userOauth.getOpenId())
						.templateId(noticeTemplate.getMaId())
						.page(StringUtil.isBlank(noticeTemplate.getMaUrl()) ?  "" : noticeTemplate.getMaUrl())
						.data(data)
						.build();
					try {
						wxMaService.getMsgService().sendSubscribeMsg(subscribeMessage);
					} catch (WxErrorException e) {
						log.error("【微信订阅消息】发送失败, {}", e.getMessage());
					}
				}
			}
		}

		//商家入住审核通知
		if(NoticeTypeEnum.SELLER_AUDIT.getType().equals(noticeDTO.getType())){
			if(noticeTemplate.getIsSms() == 1){
				SellerApply sellerApply = sellerApplyService.getById(noticeDTO.getTargetId());
				Map<String, String> params = new HashMap<>(3);
				params.put("name", sellerApply.getLegalPerson());
				params.put("results", sellerApply.getStatus() == 1 ? "已通过" : "未通过");
				params.put("platformName", "云南数字平台");
				SmsData smsData = new SmsData(params);
				SmsResponse smsResponse = smsBuilder.template(noticeTemplate.getSmsId()).sendMessage(smsData, Func.toStrList(sellerApply.getMobile()));
				log.info("商家入驻审核短信发送结果：{}", JsonUtil.toJson(smsResponse));
			}
		}

		//分销员审核通知
		if(NoticeTypeEnum.PLACE_AUDIT.getType().equals(noticeDTO.getType())){
			if(noticeTemplate.getIsSms() == 1){
				PlaceApply placeApply = placeApplyService.getById(noticeDTO.getTargetId());
				Map<String, String> params = new HashMap<>(3);
				params.put("name", placeApply.getName());
				params.put("results", placeApply.getStatus() == 1 ? "已通过" : "未通过");
				params.put("platformName", "云南数字平台");
				SmsData smsData = new SmsData(params);
				SmsResponse smsResponse = smsBuilder.template(noticeTemplate.getSmsId()).sendMessage(smsData, Func.toStrList(placeApply.getMobile()));
				log.info("分销员审核短信发送结果：{}", JsonUtil.toJson(smsResponse));
			}
		}
	}
}
